/**
 * @author luguoxiang
 * @date 2022/7/5
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
import {
  dateFormat,
  deepCopy,
  distinct,
  getFileAccessAuthUrl,
  IConfigSchema,
  ITableSchema,
  LgUploadProps,
  toLabelMap,
  toStringArray,
} from '@/soar';
import { dateFmt, datetimeFmt, timeFmt } from '@/config/global';

/**
 * 生成表格配置
 * @param config
 */
function toColumn(config: IConfigSchema<unknown> | ITableSchema<unknown>): object {
  let table;
  if (config.table) {
    table = config.table;
    table.params ??= config.params;
    table = deepCopy(table, true);
    // 基本字段复制
    table.field ??= config.field;
    table.label ??= config.label;
    table.dataType ??= config.dataType;
    table.predicate ??= config.predicate;
  } else {
    table = deepCopy(config, true);
    delete table.detail;
    delete table.form;
    delete table.search;
  }
  delete table.order;

  table.colKey ??= table.field;
  // 插槽处理
  if (typeof table.slots === 'string') {
    table.slots = { default: table.slots };
  } else {
    table.slots ??= {};
  }
  // 默认插槽
  if (table.slots.default) {
    table.cell = table.slots.default;
  }
  // 标题插槽
  if (table.slots.title) {
    table.title = table.slots.title;
  } else {
    table.title ??= table.label;
  }

  if (!table.slots.default) {
    // 数据类型处理
    switch (table.dataType) {
      case 'number':
        table.align ??= 'right';
        break;
      case 'dict':
        table.align ??= 'center';
        break;
      case 'datetime':
        table.params ??= datetimeFmt;
        table.cell ??= (h, { row }) => dateFormat(row[table.colKey], table.params);
        table.align ??= 'center';
        break;
      case 'date':
        table.params ??= dateFmt;
        table.cell ??= (h, { row }) => dateFormat(row[table.colKey], table.params);
        table.align ??= 'center';
        break;
      case 'time':
        table.params ??= timeFmt;
        table.cell ??= (h, { row }) => dateFormat(row[table.colKey], table.params);
        table.align ??= 'center';
        break;
      case 'enum':
        // eslint-disable-next-line no-case-declarations
        const mapper = toLabelMap(table.params);
        table.cell ??= (h, { row }) => mapper[row[table.colKey]];
        table.align ??= 'center';
        break;
      case 'boolean':
        if (table.params) {
          const mapper = toLabelMap(table.params);
          table.cell ??= (h, { row }) => mapper[row[table.colKey]];
        } else {
          table.cell ??= (h, { row }) => (row[table.colKey] ? '是' : '否');
        }
        table.align ??= 'center';
        break;
      case 'img':
        switch (table.params as LgUploadProps['valueType']) {
          case 'urlList':
            table.cell ??= (h, { row }) =>
              h(
                'div',
                { class: 'lg-table-imgs' },
                row[table.colKey]?.map((x) => h('img', { src: getFileAccessAuthUrl(x, 's'), class: 'lg-table-img' })),
              );
            break;
          default:
            table.cell ??= (h, { row }) =>
              h('img', { src: getFileAccessAuthUrl(row[table.colKey], 's'), class: 'lg-table-img' });
        }
        table.align ??= 'center';
        break;
      case 'file':
        table.cell ??= (h, { row }) => getFileAccessAuthUrl(row[table.colKey]);
        break;
      default:
        break;
    }
  }

  return table;
}

/**
 * 获取表格配置
 * @param fieldList
 */
function getColumns(fieldList: Array<IConfigSchema<unknown> | ITableSchema<unknown>>): object[] {
  return (
    fieldList
      // 过滤
      .filter((x: any): boolean => {
        if (x.table === false) {
          return false;
        }
        if (x.table?.predicate?.() === false) {
          return false;
        }
        return x.predicate?.() !== false;
      })
      // 排序
      .sort((a, b) => {
        if (a.table) {
          a = a.table;
        }
        if (b.table) {
          b = b.table;
        }
        return (a.order ?? 0) - (b.order ?? 0);
      })
  );
}

export function getDefault(
  cfg: any,
  defCfg: { colKey: string; title: string; width: number; align?: string; fixed: string; type?: string },
) {
  if (typeof cfg === 'object') {
    return cfg;
  }
  return defCfg;
}

export function handleColumns(props: any) {
  // 获取列配置
  let columns: any[] = getColumns(props.schema);
  // 处理列配置
  const propsColumn = props.column; // 默认列配置
  // 处理列数据、查询字段、字典字段、排序字段
  const slots = [];
  const dictSlots: any[] = [];
  const fields = distinct(toStringArray(props.fields));
  const orderMap: any = {};
  columns = columns.map((x: any) => {
    x = toColumn(x);
    // 默认值处理
    x = { ...propsColumn, ...x };
    // 查询字段
    if (typeof x.field === 'string' && !fields.includes(x.field)) {
      fields.push(x.field);
    }
    // 排序字段
    if (x.sorter) {
      if (typeof x.sorter === 'string') {
        orderMap[x.field] = x.sorter;
      } else {
        orderMap[x.field] = x.field;
      }
    }
    // 字典字段
    if (x.dataType === 'dict' && !x.slots.default) {
      dictSlots.push({
        code: x.params,
        field: x.colKey,
      });
    }
    // 插槽
    for (const slotsKey in x.slots) {
      slots.push(x.slots[slotsKey]);
    }
    delete x.slots;
    delete x.field;
    delete x.label;
    return x;
  });
  // 序号列
  if (props.index) {
    const index = getDefault(props.index, {
      colKey: 'serial-number',
      title: '序号',
      width: 60,
      align: 'right',
      fixed: 'left',
    });
    columns.unshift(index);
  }
  // 选择列
  if (props.selection) {
    const selection = getDefault(props.selection, {
      colKey: 'row-select',
      title: '多选',
      type: 'multiple',
      width: 50,
      fixed: 'left',
    });
    columns.unshift(selection);
  }
  // 操作列
  if (props.actionbar) {
    const actionbar = {
      colKey: 'actionbar',
      cell: 'actionbar',
      title: '操作',
      fixed: 'right',
      width: 100,
      className: 'lg-table-actionbar',
      ...(typeof props.actionbar === 'object' ? props.actionbar : {}),
    };
    columns.push(actionbar);
    slots.push(actionbar.cell);
  }
  // 返回处理结果
  return {
    // 需查询的字段
    fields,
    // 列信息
    columns,
    // 默认排序字段
    defaultOrderBys: toStringArray(props.orderBys),
    // 排序映射
    orderMap,
    // 数据字典插槽
    dictSlots,
    // 插槽
    slots,
  };
}
